package example.telosys.persistence;

import java.util.HashMap;
import java.util.List;

import org.demo.vo.bean.Book;
import org.demo.vo.bean.Publisher;
import org.telosys.persistence.PersistenceManager;
import org.telosys.persistence.PersistenceManagerFactory;
import org.telosys.persistence.Query;
import org.telosys.persistence.TelosysPersistence;
import org.telosys.persistence.sql.Criteria;
import org.telosys.persistence.sql.Criterion;
import org.telosys.persistence.sql.CriterionType;

public class LoadLinks {

	public static void main(String[] args) {
		
		PersistenceManagerFactory pmf = TelosysPersistence.getPersistenceManagerFactory() ;
		PersistenceManager pm = pmf.createPersistenceManager() ;
		
		Publisher p ;
		if ( ( p = pm.loadByKey(Publisher.class, 1) ) != null ) {
			System.out.println("Found : " + p);
			
			//--- Load link "ToMany"
			loadBooks(pm, p );
			
			//--- Same operation with pm 

			System.out.println("-------- load links with PM (without link name)" );
			{
				List<Book> books = pm.loadLinks(Book.class, p ) ;
				if ( books != null ) {
			        printBooks(books) ;
				}
				else {
					System.out.println("Publisher books not found" );
				}
			}
			
			System.out.println("-------- load links with PM (with link name)" );
			{
				List<Book> books = pm.loadLinks(Book.class, p, "books" ) ;
				if ( books != null ) {
			        printBooks(books) ;
				}
				else {
					System.out.println("Publisher books not found" );
				}
			}
			
		}
		else {
			System.out.println("Not found");
		}
		
		pm.close();		
	}

	private static void loadBooks(PersistenceManager pm, Publisher p ) {
		HashMap<String, Object> queryParameters = new HashMap<String,Object>();
		queryParameters.put("publisherId", p.getCode() );

		Criterion[] criterionArray = { 
		    	// Criteria with field names ( $fieldName )
				new Criterion("$publisherId = ?",  CriterionType.INT,  "publisherId" ) 
		    };	
		Criteria criteria = new Criteria(criterionArray);
		criteria.applyParameters( queryParameters );

		Query<Book> query = pm.createQuery(Book.class, criteria);
        List<Book> books = pm.loadByQuery(query);
        
        printBooks(books) ;
	}
	
	private static void printBooks(List<Book> books) {
        System.out.println("Books loaded : " + books.size() );
		for ( Book book : books ) {
			System.out.println(" . " + book );
		}
	}
	
//	// Many to One
//	private static Object loadLink(PersistenceManager pm, Publisher entity ) {
//		
//		Class<?> expectedType = Country.class ;
//		String countryCode = entity.getCountryCode();
//		
//		// for each key part ...
//		Object[] keyParts = new Object[1] ;
//		keyParts[0] = countryCode ;
//		
//		// check at least one key part not null 
//		boolean oneKeyPartNotNull = false ;
//		for ( Object o : keyParts ) {
//			if ( o != null ) {
//				oneKeyPartNotNull = true ;
//			}
//		}
//		
//		Object o = null ;
//		if ( oneKeyPartNotNull ) {
//			o = pm.loadByKey(expectedType, keyParts ) ;
//			if ( o != null ) {
//				System.out.println("Link found : " + o );
//			}
//			else {
//				System.out.println("Link not found" );
//			}
//		}
//		else {
//			System.out.println("All key parts are null " );
//		}
//		return o ;
//	}
	
//	// One to Many
//	private static Object loadLinks(PersistenceManager pm, Publisher entity ) {
//		
//		Class<?> expectedType = Book.class ;
//		String countryCode = entity.getCountryCode();
//		
//		// for each key part ...
//		Object[] keyParts = new Object[1] ;
//		keyParts[0] = countryCode ;
//		
//		// check at least one key part not null 
//		boolean oneKeyPartNotNull = false ;
//		for ( Object o : keyParts ) {
//			if ( o != null ) {
//				oneKeyPartNotNull = true ;
//			}
//		}
//		
//		Criteria criteria ;
//		criteria.applyParameters( parameters );
//
//		Query<Book> query = pm.createQuery(Book.class, criteria);
//	}
	
//	private Criteria buildLinkCriteria(EntityMapper<?> entityMapper, LinkMapping linkMapping) {
//
//		LinkedList<Criterion> listOfCriterion = new LinkedList<Criterion> ();
//		Map<String,Object> parameters = new HashMap<String,Object>();
//		
//		String[] keyParts = linkMapping.getKeyParts();
//		for ( String fieldName : keyParts ) {
//			// for each key part field name ( ie "publisherId",... )
//			
//			FieldMapper fieldMapper = entityMapper.getFieldMapper(fieldName)
//			String symbolicFieldName = "$" + fieldName ;
//			int    fieldType = fieldMapper.getTypeForQuery() ;
//			
//			
//			Criterion criterion = new Criterion( fieldName + " = ?", fieldType, fieldName ) ;
//			//new Criterion("$publisherId = ?",  ParamType.INT,    "publisherId" ) ;
//
//			listOfCriterion.add(criterion);
//			parameters.put(fieldName, value);
//		}
//		
//		
//		Criterion[] voidArray = {} ;
//		Criterion[] arrayOfCriterion = listOfCriterion.toArray( voidArray );
//		
//		Criteria criteria = new Criteria(arrayOfCriterion);
//		return criteria ;
//	}
}
